package com.matt.sooncleaner.junk

import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.AsyncTask
import android.os.Handler
import android.os.Looper
import android.provider.MediaStore
import android.view.View
import androidx.core.net.toUri
import androidx.core.view.WindowCompat
import androidx.lifecycle.lifecycleScope
import com.blankj.utilcode.util.BarUtils
import com.blankj.utilcode.util.FileUtils
import com.blankj.utilcode.util.ThreadUtils
import com.blankj.utilcode.util.UriUtils
import com.matt.sooncleaner.R
import com.matt.sooncleaner.arch.ArchFragment
import com.matt.sooncleaner.databinding.FragmentCleanProgressBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
import java.io.File

class CleanProgressFragment : ArchFragment<FragmentCleanProgressBinding>() {
    interface CleanFinishListener {
        fun onCleanFinish()
    }

    private val mJunkResult = mutableListOf<JunkBean>()
    private val mDeleteFinishFlow = MutableSharedFlow<Boolean>()
    private val mCountTimeFinishFlow = MutableSharedFlow<Boolean>()
    private val mExitFlow =
        mDeleteFinishFlow.combine(mCountTimeFinishFlow) { sen, room -> sen && room }
    private var mCleanFinishListener: CleanFinishListener? = null
    private val mCountTimeHandler = Handler(Looper.getMainLooper())
    private val mCountTimeRunnable = Runnable {
        if (!isAdded) {
            return@Runnable
        }
        lifecycleScope.launch {
            mCountTimeFinishFlow.emit(true)
        }
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        if (context is CleanFinishListener) {
            mCleanFinishListener = context
        }
    }

    override fun onInitView(binding: FragmentCleanProgressBinding) {
        super.onInitView(binding)
        BarUtils.setStatusBarLightMode(requireActivity(), true)
        BarUtils.setStatusBarColor(
            requireActivity(),
            resources.getColor(R.color.windowbackground_color)
        )
        lifecycleScope.launch {
            mExitFlow.collectLatest {
                if (it) {
                    mCleanFinishListener?.onCleanFinish()
                }
            }
        }
        lifecycleScope.launch {
            deleteAllFile()
        }
        mCountTimeHandler.postDelayed(mCountTimeRunnable, 5000)
    }

    private fun List<JunkBean>.totalSize(): Long {
        val sizeList = map { it.size }
        var totalSize = 0L
        sizeList.forEach { totalSize += it }
        return totalSize
    }

    private suspend fun deleteAllFile() {
        withContext(Dispatchers.IO) {
            suspendCancellableCoroutine<Any> { cancelable ->
                kotlin.runCatching {
                    val allList = mutableListOf<String>()
                    mJunkResult.forEach {
                        if (cancelable.isCancelled) return@suspendCancellableCoroutine
                        it.junkChildrenItem.forEach { child ->
                            if (cancelable.isCancelled) return@suspendCancellableCoroutine
                            if (child.isAppCache) {
                                allList.addAll(child.appCacheBeens.map { appCacheBean -> appCacheBean.path })
                            } else {
                                allList.add(child.path)
                            }
                        }
                    }

                    if (cancelable.isCancelled) {
                        return@suspendCancellableCoroutine
                    }
                    if (allList.isEmpty()) {
                        lifecycleScope.launch {
                            mDeleteFinishFlow.emit(true)
                        }
                        return@suspendCancellableCoroutine
                    }

                    allList.forEachIndexed { index, s ->
                        if (cancelable.isCancelled) {
                            return@suspendCancellableCoroutine
                        }
                        deleteFile(s)
                        if (index == allList.lastIndex) {
                            lifecycleScope.launch {
                                mDeleteFinishFlow.emit(true)
                            }
                        }
                    }
                }
            }
        }
    }

    fun setJunkResult(result: MutableList<JunkBean>) {
        mJunkResult.addAll(result)
    }

    private fun deleteFile(filePath: String) {
        kotlin.runCatching {
            println("deleteError:$filePath")
            if (filePath.startsWith("/external/video")) {
                deleteFile(MediaUtils.getPath(filePath))
            } else {
                if (CleanManager.getCleanSdk()?.delete(File(filePath)) == false) {
                    FileUtils.delete(filePath)
                }
                val contentUri = Uri.fromFile(File(filePath))
                val mediaScanIntent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,contentUri)
                requireActivity().sendBroadcast(mediaScanIntent)
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        mCountTimeHandler.removeCallbacks(mCountTimeRunnable)
    }
}